package rs.etf.mips.crossroad;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import rs.etf.mips.crossroad.logic.Crossroad;

/**
 * Main class for running the application.
 */
public class Simulation implements Runnable {

	private long iterationPeriod;

	private List<IDraw> drawers;

	private Crossroad crossroad;
	private volatile Thread thread;
	private volatile boolean paused;
	private Object syncObj;

	public Simulation(long iterationPeriod, Crossroad crossroad) {
		super();
		this.iterationPeriod = iterationPeriod;
		this.drawers = new ArrayList<IDraw>();
		this.crossroad = crossroad;
		this.paused = false;
		this.syncObj = new Object();
	}

	public void run() {
		while (true){
			synchronized (syncObj) {
				if (Thread.currentThread() != this.thread) break;
			}
			if (!paused()) {
				this.update();
				this.draw();
				try {
					Thread.sleep(iterationPeriod);
				} catch (InterruptedException e) {
				}
			} else {
				try {
					syncObj.wait();
				} catch (InterruptedException e) {
				}
			}
		
			
		}
	}

	private boolean paused(){
		synchronized (syncObj) {
			return paused;
		}
	}
	
	public void start() {
		synchronized (syncObj) {
			thread = new Thread(this);
			thread.start();
			syncObj.notifyAll();
		}
	}

	public void stop() {
		synchronized (syncObj) {
			thread = null;
			syncObj.notifyAll();
		}
	}

	public void pause() {
		synchronized (syncObj) {
			paused = true;
		}
	}

	public void resume() {
		synchronized (syncObj) {
			paused = false;
			syncObj.notifyAll();
		}
	}

	public long getIterationPeriod() {
		return this.iterationPeriod;
	}

	public void setIterationPeriod(final long value) {
		this.iterationPeriod = value;
	}

	public List<IDraw> getIDraw() {
		return this.drawers;
	}
	
	public boolean addIDraw(IDraw drawer) {
		return this.drawers.add(drawer);
	}
	
	public boolean removeIDraw(IDraw drawer) {
		return this.drawers.remove(drawer);
	}

	public Crossroad getCrossroad() {
		return this.crossroad;
	}

	private void update() {
		this.crossroad.update();
	}

	private void draw() {
		for (IDraw draw : drawers) {
			draw.draw(crossroad);
		}
	}

	public static void main(String [] args){
		Simulation sim = new Simulation(100, new Crossroad(100, 30, 2));
		sim.addIDraw(new IDraw() {
			
			@Override
			public void draw(Crossroad crossroad) {
				System.out.println("a");
			}
		});
		sim.start();
		Scanner s = new Scanner(System.in);
		s.nextLine();
		sim.stop();
	}
	
}
